/*
 * main.c
 *
 *  Created on: Nov 30, 2011
 *      Author: Christian St�veken christian.Stoeveken@googlemail.com
 *      Author: Jonas Wilhelm wilheljo@googlemail.com
 *      Author: Jannik Müller jannik-mpunkt@web.de
 */

typedef struct TMC222Sta
{
        unsigned char IHold: 4;
        unsigned char IRun: 4;
        unsigned char VMin: 4;
        unsigned char VMax: 4;
        unsigned char Acc: 4;
        unsigned char Shaft: 1;
        unsigned char StepMode: 2;
        unsigned char AccShape: 1;
        unsigned char TInfo: 2;
        unsigned char TW: 1;
        unsigned char TSD: 1;
        unsigned char UV2: 1;
        unsigned char ElDef: 1;
        unsigned char SteppLoss: 1;
        unsigned char VddReset: 1;
        unsigned char CPFail: 1;
        unsigned char NA: 1;
        unsigned char OVC2: 1;
        unsigned char OVC1: 1;
        unsigned char ESW: 1;
        unsigned char Motion: 3;
} TTMC222Status;

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "Clock.h"
#include "LCD.h"
#include "Sensors.h"
#include "System.h"
#include "Touchscreen.h"

/* SCREENS */
#define MMENU 0
#define HOME 1
#define PARAMS 2
#define INTERVAL 3
#define CHANGESLOT 4
#define ACTIVATE 5
#define STDBY 6

/* SYSTEM CONSTANTS */
#define INITIAL_STEPSX 10
#define STEPSPERSLOT 5
#define STEPSPERML 1

struct slotValues {
    int interval,
        dose,
        timeOfLastDose,
        slotActive;
};

struct slotValues slot[7];


void inject(int slotIndex) {
    moveX(INITIAL_STEPSX + (slotIndex*STEPSPERSLOT));
    moveY(STEPSPERML*slot[slotIndex].dose);
    resetY();
    resetX();
}

/*checks if some dose is due now and returns for
  every slot the time left until the next dose
  CURRENTLY INTERVAL IS SET TO SOME FIX VALUE*/
void checkIfInjectionNeeded(int* timeLeftTilNext){
    int i;
        
    for(i=0;i<7;i++){
        timeLeftTilNext[i] = (slot[i].timeOfLastDose+slot[i].interval)- getTime();
        if((slot[i].slotActive!=0)
             &&
           (timeLeftTilNext[i]<0)){
            printf("\nStarting injection (%d ml/slot %d)\n", slot[i].dose, i);
            inject(i);
            slot[i].timeOfLastDose = getTime();
            timeLeftTilNext[i] = (slot[i].timeOfLastDose+slot[i].interval)- getTime();
        }
    }
}


void changeParameters(int slotIndex){
    int input;
    
    printf("current interval for slot %i: %i\nnew interval: ", slotIndex, slot[slotIndex].interval);
            fflush(stdout);
            scanf("%d", &input);
            slot[slotIndex].interval = input;
    
    printf("current dose for slot %i: %i\nnew interval: ", slotIndex, slot[slotIndex].dose);
            fflush(stdout);
            scanf("%d", &input);
            slot[slotIndex].dose = input;
            
            //store the value on flash
            storeValue(slotIndex, DOSE, slot[slotIndex].dose);
            storeValue(slotIndex, TIME_INTERVAL, slot[slotIndex].interval);
    
    printf("Slot %i:\ninterval: %i\ndose:%i\nValues successfully saved!\n", slotIndex, slot[slotIndex].interval, slot[slotIndex].dose);
}

void menu(int screen) {
    int option, option2, params[7], timeLeft[7], i;
    
    switch(screen) {
        case MMENU:
            
            printf("[1] Home\n");
            printf("[2] Metering parameters\n");
            printf("[3] Metering intervals\n");
            printf("[4] Alter Slot configuration\n");
            printf("[5] Activate/Deactivate Slot\n");
            printf("[6] Enable Metering System\n\n");

            fflush(stdout);
            scanf("%d", &option);
            
            menu(option);
            break;
            
        case HOME:
            printf("Homescreen with time remaining til next dosing session goes here\n");
            break;
            
        case PARAMS:
            printf("Please enter your metering parameters:\n");
            
            for(i=0;i<=6;i++){
                printf("Slot %d:", i+1);
                fflush(stdout);
                scanf("%d", &slot[i].dose);
            }          
            
            printf("\n\n");
            
            i=0;
            
            for(i; i<=6; i++) {
                printf("Slot %i: %i \n", i, params[i]);
            }
            
            break;
            
        case INTERVAL:
            printf("Please define your metering intervals:\n");
            
            for(i=0;i<=6;i++){
                printf("Slot %d:", i+1);
                fflush(stdout);
                scanf("%d", &slot[i].interval);
            }
            
            for(i=0; i<=6; i++) {
                printf("Slot %i: %i \n", i, params[i]);
            }
            
            break;
            
        case CHANGESLOT:
            printf("Please state slot number to alter[1-7]: ");
            
            fflush(stdout);
            scanf("%d", &option);
            
            printf("\n");
            changeParameters(option);
            option = MMENU;
            break;
        
        case ACTIVATE:
            printf("Please state slot number to activate/deactivate[1-7]\nTo activate/deactivate all, enter '8': ");
            
            fflush(stdout);
            scanf("%d", &option);
            
            while((option2!=0) && (option2!=1)){
                printf("\n[0] for deactivation, [1] for activation: ");
                fflush(stdout);
                scanf("%d", &option2);
                printf("\n");
                if((option2!=0) && (option2!=1)) printf("Wrong input\n\n");
            }
            
            if(option<=7){
                slot[option-1].slotActive = option2;
            } else if(option == 8){
                for (i=0;i<7;i++)       slot[i].slotActive = option2;
            } else{
                printf("Illegal slot number!\n");
            }
            
            option = MMENU;
            break;
            
        case STDBY:
            printf("Entering standby mode...\n");
            for(;;){
                
                checkIfInjectionNeeded(timeLeft);
                for(i=0;i<=6;i++){
                    if(slot[i].slotActive!=0) printf("Slot %d: %d sec left\n", (i+1), timeLeft[i]);
                    else                      printf("Slot %d: DEACTIVATED\n", (i+1));
                }
                
                printf("you are stuck in this loop until you kill the program\n\n\n");
                
                sleep(1);
            }
            
            option = MMENU;
            
            break;
            
        default:
            printf("Unknown action, loading menu...\n");
            menu(MMENU);
            break;
    }
}

int main() {
        int i;
        //init storage to set all values in the "fake" storage to 0
        bootstrap();
        
        //Load the saved doses and intervals
        for(i=0;i<7;i++){
            slot[i].dose = loadValue(i, DOSE);
            slot[i].interval = loadValue(i, TIME_INTERVAL);
            slot[i].slotActive = loadValue(i, SLOT_ACTIVE);
        }
        
        int8_t plus = 6;
        int8_t minus = -6;
        
        printf("+6: ");
        bit_print((char*)&plus, 8);
        printf("-6: ");
        bit_print((char*)&minus, 8);

	while (1) {
		menu(MMENU);
	};
	return 999;
}

bit_print(char* data, int length)
{
	unsigned char mask = 0x01;
	int ptr = 0;
	int bit = 0;
	for(;ptr < length;ptr++)
	{
		for(bit = 7;bit >= 0;bit--)
		{
			if ((mask << bit) & (unsigned char)*(data+ptr))
			{
				printf("1");
			}
			else
			{
				printf("0");
			}
		}
		printf(" ");
	}
	printf("\n");
}
